import _ from 'lodash';

// 筛选全部的下一步
function flattenObject(ob, jumpTo) {
	for (let i in ob) {
		if (!ob.hasOwnProperty(i)) {
			continue;
		}

		if (typeof ob[i] === 'object' && ob[i] !== null) {
			let flatObject = flattenObject(ob[i], jumpTo);
			for (let x in flatObject) {
				if (!flatObject.hasOwnProperty(x)) {
					continue;
				}
			}
		} else if (ob[i] === 'jump-to') {
			jumpTo.push(ob);
		}
	}
}
function includesArray(data, arr) {
	return data.some(e => Array.isArray(e) && e.every((o, i) => Object.is(arr[i], o)));
}

// 获取主流程的所有分支
function getBranches(worksteps, startNodeId) {
	// console.log(' getBranches start');
	let flatten = {};
	for (let item in worksteps) {
		let jumpTo = [];
		flattenObject(worksteps[item], jumpTo);
		if (jumpTo.length > 0) {
			flatten[item] = jumpTo;
		}
	}
	flatten = _.cloneDeep(flatten);

	if (!flatten[startNodeId]) {
		return [];
	}

	let result = [];
	function getPath(nodes, arr, nodeId) {
		let repeat = false;
		// 如果循环，退出递归
		if (arr.includes(nodeId)) {
			repeat = true;
			arr.push(nodeId);
		} else {
			arr.push(nodeId);
		}
		if (nodes[nodeId] && nodes[nodeId].length > 0 && !repeat) {
			for (let i = 0; i < nodes[nodeId].length; i++) {
				getPath(nodes, [...arr], nodes[nodeId][i].id);
			}
		} else {
			result.push(arr);
		}
	}
	getPath(flatten, [], startNodeId);
	console.log(' getBranches end');
	return result;
}

// 获取主流程的节点
function getMainNodeList(branches) {
	// 获取主流程的节点
	let mainNodeList = [];
	for (const branch of branches) {
		for (const node of branch) {
			if (!mainNodeList.includes(node)) {
				mainNodeList.push(node);
			}
		}
	}
	return mainNodeList;
}
function includesNode(text) {
	if (!text) {
		return false;
	}
	return text.includes('messageCollect') || text.includes('soundReception') || text.includes('requestLocation') || text.includes('variableCollection');
}
// 判断节点中的关联变量是否与输入变量相同
function isSameVariable(workstep, variable, initMode = true) {
	// 判断是否关联该变量
	let result = false;
	if (includesNode(workstep.id)) {
		if (workstep && workstep.associatedVariable && workstep.associatedVariable.name === variable.name) {
			// 确认子节点中是否引用该变量
			if (initMode && workstep.associatedVariable.initMode === 'non-init') {
				result = true;
			}
			result = true;
		}
	}
	return result;
}

function isAssociatedVariableTemplete(step) {
	if (!step || !step.id) {
		return false;
	}
	return includesNode(step.id);
}

// 获取主流程的所有引用非初始化变量的模板其父节点没有对其赋值的模板的变量
const getBranchesHasNonInitVariable = function (worksteps, startNodeId, nonInitVariableList) {
	if (!nonInitVariableList || nonInitVariableList.length <= 0) {
		return [];
	}
	const branches = getBranches(worksteps, startNodeId);
	// 获取主流程的节点
	const mainNodeList = getMainNodeList(branches);
	const workstepsText = JSON.stringify(worksteps);
	let result = [];
	for (let variable of nonInitVariableList) {
		if (!workstepsText.includes(`{{${variable.name}}}`)) {
			continue;
		}
		for (const key in worksteps) {
			// 判断节点在主流程中
			if (!mainNodeList.includes(key)) {
				continue;
			}
			const workstepText = JSON.stringify(worksteps[key]);
			if (workstepText.includes(`{{${variable.name}}}`)) {
				let isBreakRule = false;
				// 判断父节点关联该变量
				for (const branch of branches) {
					if (!branch.includes(key)) {
						continue;
					}
					let branchText = JSON.stringify(branch);
					if (!includesNode(branchText)) {
						isBreakRule = true;
						break;
					}
					// 判别父子关系
					const index = branch.indexOf(key);
					console.warn('branch : ', branch, key);
					branchText = JSON.stringify(branch.slice(0, index));
					if (!includesNode(branchText)) {
						isBreakRule = true;
						break;
					}
					// 判断是否关联该变量
					let found = false;
					// 从下往上追踪
					for (let i = index - 1; i >= 0; i--) {
						const workstep = worksteps[branch[i]];
						found = isSameVariable(workstep, variable, true);
						if (found) {
							let step = workstep;
							// 是否为无结果分支
							const nextstep = worksteps[branch[i + 1]];
							if (step.errorRemind && step.errorRemind.do && step.errorRemind.do.id === nextstep.id) {
								found = false;
								break;
							}
							// answer
							if (step.answer && step.answer[1] && step.answer[1].do.id === nextstep.id) {
								found = false;
								break;
							}
							break;
						}
					}
					isBreakRule = !found;
				}
				if (isBreakRule) {
					result.push(variable);
					// 已找到，退出循环
					break;
				}
			}
		}
	}
	return result;
};

// 校验关联变量中是否包含未作废变量
const validateInvalidVariable = function (worksteps, startNodeId, invalidVariables) {
	if (!invalidVariables || invalidVariables.length <= 0) {
		return [];
	}
	const branches = getBranches(worksteps, startNodeId);
	// 获取主流程的节点
	const mainNodeList = getMainNodeList(branches);
	let result = [];
	for (let variable of invalidVariables) {
		for (const key in worksteps) {
			// 判断节点是3类模板之一
			if (!key.includes('messageCollect') && !key.includes('soundReception') && !key.includes('requestLocation')) {
				continue;
			}
			// 判断节点在主流程中
			if (!mainNodeList.includes(key)) {
				continue;
			}
			if (!isSameVariable(worksteps[key], variable, false)) {
				continue;
			}
			const data = {
				workstep: worksteps[key],
				variable: variable
			};
			// 去重
			let found = false;
			for (let item of result) {
				if (item.workstep.id === worksteps[key].id && item.variable.id === variable.id) {
					found = true;
					break;
				}
			}
			if (!found) {
				result.push(data);
			}
		}
	}
	return result;
};

export { getBranchesHasNonInitVariable, validateInvalidVariable, isSameVariable, isAssociatedVariableTemplete, getBranches };
